/**
 * 输出一个有效地时间戳
 * @param {timestamp} time 时间戳
 */
export function formatTimestamp(time) {
    if (!time) {
        return 0
    }

    if (Object.prototype.toString.call(time) === '[object Date]') {
        return time.getTime()
    }

    if (typeof time === 'string' && !/^\d+$/gi.test(time)) {
        // 兼容 safari Date 格式 只能是 YYYY/MM/DD
        time = time.replace(/-/g, '/')

        try {
            time = (new Date(time)).getTime()

            if (time) {
                return time
            }
        } catch (e) {
            time = 0

            console.warn('timestamp 的参数错误')
        }
    }

    if (time) {
        time += ''

        if (time.length < 12) {
            // const length = 13 - time.length
            // time = time * Math.pow(10, length > 1 ? length : 0)

            // 在确认为秒的时候，固定为 3 位
            time = time + '000'
        }

        return time - 0
    }

    return 0
}

/**
 * 日期过滤器
 * @type Function
 * @param {Date}    timestamp  时间戳
 * @param {String}  type       转换类型，format 为空时为 format [timestamp:时间戳,near:就近时间]
 * @param {String}  [format]   输出规范 [YYYY:年份,MM:补零的月份,M:月份,DD补零的日期:,D日期:,hh:小时,mm:分,ss:秒]
 */
function formatDate(timestamp, type, format) {
    if (type === 'today') {
        timestamp = Date.now()
    }

    if (type === 'Date') {
        return new Date(timestamp)
    }

    timestamp = formatTimestamp(timestamp)

    switch (type) {
        case 'timestamp':
            return timestamp
        case 'near':
            return near(timestamp, format)
        default:
            break
    }

    if (timestamp) {
        let _date = getDate(timestamp)
        let _year = _date.year
        let _month = _date.month + ''
        let _day = _date.day + ''
        let _hour = _date.hour + ''
        let _minute = _date.minute + ''
        let _seconds = _date.seconds + ''

        let weekMap = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']

        // 快捷返回的 Date 数据
        let resultDate

        switch (type) {
            case 'today':
                resultDate = new Date(_year, _month - 1, _day, 1, 0, 0)
                break
            case 'prevDay':
                resultDate = new Date(_year, _month - 1, --_day)
                break
            case 'nextDay':
                resultDate = new Date(_year, _month - 1, ++_day)
                break
            case 'prevWeek':
                resultDate = new Date(_year, _month - 1, -7)
                break
            case 'nextWeek':
                resultDate = new Date(_year, _month - 1, (_day | 0) + 7)
                break
            case 'prevMonth':
                resultDate = new Date(_year, _month - 2, 1)
                break
            case 'nextMonth':
                resultDate = new Date(_year, _month, 1)
                break
            case 'prevYear':
                resultDate = new Date(_year - 1, _month - 1, 1)
                break
            case 'nextYear':
                resultDate = new Date(_year + 1, _month - 1, 1)
                break
            case 'year':
                format = 'YYYY 年 MM 月 DD 日'
                break
            case 'date':
                format = 'M 月 D 日 hh:mm'
                break
            case 'datepicker':
                format = 'YYYY-MM-DD hh:mm:ss'
                break
            case 'time':
                format = 'hh:mm:ss'
                break
            default:
                break
        }

        if (resultDate) {
            return format ? formatDate(resultDate, format) : resultDate
        }

        // 默认只传两个参数， format 值为 type
        if (!format) {
            format = type
        }

        format = format.replace('YYYY', _year)
        format = format.replace('MM', _month.padStart(2, '0'))
        format = format.replace('M', _month)
        format = format.replace('DD', _day.padStart(2, '0'))
        format = format.replace('D', _day)

        format = format.replace('hh', _hour.padStart(2, '0'))
        format = format.replace('mm', _minute.padStart(2, '0'))
        format = format.replace('ss', _seconds.padStart(2, '0'))

        format = format.replace('W', weekMap[_date.date.getDay()])

        return format
    }

    return ''
}

// 根据参考时间，获取距离最近时间的文案
export function near(timestamp, format = 'YYYY 年 MM 月 DD 日 hh:mm') {
    const minutes = (Date.now() - timestamp) / 1000 / 60 | 0
    const minute = minutes % 60 | 0
    const hour = minutes / 60 | 0
    // const day = hour / 24 | 0

    if (hour === 0) {
        return minute < 10 ? '刚刚' : `${minute} 分钟前`
    } else if (hour < 24) {
        return `${hour} 小时前`
    } else {
        // return day < 8 ? `${day} 天前` : date(timestamp, format)
        return formatDate(timestamp, format)
    }
}

/**
 * 整合不同类型的 Date 数据，统一输出格式
 * @param {Date|String|Number} reference   参考日期
 * @param {String}             [format]    数据格式化类型，默认为 all [year,month,day,timestamp,date,morning,night,all]
 */
export function getDate(reference, format) {
    if (!reference) {
        throw Error('<Date getDate> param reference  is not define.')
    }

    const timestamp = formatTimestamp(reference)
    const date = new Date(timestamp)

    switch (format) {
        case 'date':
            return date
        case 'timestamp':
            return date.getTime()
        case 'year':
            return date.getFullYear()
        case 'month':
            return date.getMonth() + 1
        case 'day':
            return date.getDate()
        case 'morning':
            return date.setHours(0, 0, 0)
        case 'night':
            return date.setHours(23, 59, 59)
        default:
            return {
                date,
                timestamp: date.getTime(),
                year: date.getFullYear(),
                month: date.getMonth() + 1,
                day: date.getDate(),
                dayOfWeek: date.getDay(), // ISO 8601标准，周日作为一周的第一天
                hour: date.getHours(),
                minute: date.getMinutes(),
                seconds: date.getSeconds(),
                morning: date.setHours(0, 0, 0),
                night: date.setHours(23, 59, 59)
            }
    }
}

/**
 * 获取日期的第一天和最后一天
 * @param {Date|String|Number} reference   参考日期
 * @return Date 返回日期对象
 */
export function getFirstAndLastDay(reference) {
    const date = getDate(reference)
    const yearFirstDay = new Date(date.year, 0, 1)
    const yearLastDay = new Date(date.year, 11, 31)
    const monthFirstDay = new Date(date.year, date.month, 1)
    const monthLastDay = new Date(date.year, date.month + 1, 0)
    const dayOfWeek = date.getDay()
    const weekFirstDay = new Date(date)
    weekFirstDay.setDate(date.getDate() - dayOfWeek + (dayOfWeek === 0 ? -6 : 1)) // 算到周一

    const weekLastDay = new Date(weekFirstDay)
    weekLastDay.setDate(weekFirstDay.getDate() + 6) // 算到周日

    return {
        yearFirstDay,
        yearLastDay,
        monthFirstDay,
        monthLastDay,
        weekFirstDay,
        weekLastDay
    }
}

/**
 * 获取日期在当年的第几周
 * @param {Date|String|Number} reference   参考日期
 * @returns
 */
export function getWeekOfYear(reference) {
    let date = null
    try {
        date = new Date(reference)
    } catch (error) {
        console.warn(error)
    }

    if (!date) {
        return
    }

    // 获得当前年份的第一天
    const firstDayOfYear = new Date(date.getFullYear(), 0, 1)

    // 计算当前日期与年初第一天之间的天数差
    const pastDays = Math.floor((date - firstDayOfYear) / (24 * 60 * 60 * 1000))

    // 计算第几周（ISO 8601标准，周日作为一周的开始）
    const weekNumber = Math.ceil((pastDays + (firstDayOfYear.getDay() + 1)) / 7)

    return weekNumber
}


/**
 * 获取日期在当年的第几周，返回起始日期和结束日期
 * @param {Date|String|Number} reference   参考日期
 * @returns
 */
export function getWeekRangeOfYear(reference) {
    let date = null
    try {
        date = new Date(reference)
    } catch (error) {
        console.warn(error)
    }

    if (!date) {
        return
    }

    // 调整到周日（ISO 8601标准，周日作为一周的开始）
    const diff = date.getDate() - date.getDay()
    const startDate = new Date(date.setDate(diff))

    // 计算这一周的结束日期（周六）
    const endDate = new Date(startDate.getTime() + (6 * 24 * 60 * 60 * 1000))

    // 返回结果对象
    return {
        startDate,
        endDate
    }
}

/**
 * 日期选择器
 * @param {Date}    reference      参考日期
 * @param {String}  type           数据偏移类型 [prevYear|nextYear|prevMonth|nextMonth|prevWeek|nextWeek|prevDay|nextDay]
 * @param {String} [format='all']  数据格式化类型，默认为 all [year,month,day,timestamp,date,morning,night,all]
 */
export function getDatepicker(reference, type, format) {
    const allow = {
        prevYear: 1,
        nextYear: 1,
        prevMonth: 1,
        nextMonth: 1,
        prevWeek: 1,
        nextWeek: 1,
        prevDay: 1,
        nextDay: 1
    }

    if (!allow[type]) {
        throw Error(`<Gkui: Date::getDatepicker> the "${type}" is not a legal type.`)
    }

    return getDate(formatDate(reference, type), format)
}

/**
 * 获取上一年的 Date 数据
 * @param {Date}    reference     参考日期
 * @param {String} [format='all']  数据格式化类型，默认为 all [year,month,day,timestamp,date,morning,night,all]
 */
export function getPrevYearDate(reference, format) {
    return getDatepicker(reference, 'prevYear', format)
}

/**
 * 获取下一年的 Date 数据
 * @param {Date}    reference     参考日期
 * @param {String} [format='all']  数据格式化类型，默认为 all [year,month,day,timestamp,date,morning,night,all]
 */
export function getNextYearDate(reference, format) {
    return getDatepicker(reference, 'nextYear', format)
}

/**
 * 获取上一个月的 Date 数据
 * @param {Date}    reference     参考日期
 * @param {String} [format='all']  数据格式化类型，默认为 all [year,month,day,timestamp,date,morning,night,all]
 */
export function getPrevMonthDate(reference, format) {
    return getDatepicker(reference, 'prevMonth', format)
}

/**
 * 获取下一个月的 Date 数据
 * @param {Date}    reference     参考日期
 * @param {String} [format='all']  数据格式化类型，默认为 all [year,month,day,timestamp,date,morning,night,all]
 */
export function getNextMonthDate(reference, format) {
    return getDatepicker(reference, 'nextMonth', format)
}

/**
 * 获取上一周的 Date 数据
 * @param {Date}    reference     参考日期
 * @param {String} [format='all']  数据格式化类型，默认为 all [year,month,day,timestamp,date,morning,night,all]
 */
export function getPrevWeekDate(reference, format) {
    return getDatepicker(reference, 'prevWeek', format)
}

/**
 * 获取下一周的 Date 数据
 * @param {Date}    reference     参考日期
 * @param {String} [format='all']  数据格式化类型，默认为 all [year,month,day,timestamp,date,morning,night,all]
 */
export function getNextWeekDate(reference, format) {
    return getDatepicker(reference, 'nextWeek', format)
}

/**
 * 获取上一日的 Date 数据
 * @param {Date}    reference     参考日期
 * @param {String} [format='all']  数据格式化类型，默认为 all [year,month,day,timestamp,date,morning,night,all]
 */
export function getPrevDayDate(reference, format) {
    return getDatepicker(reference, 'prevDay', format)
}

/**
 * 获取下一日的 Date 数据
 * @param {Date}    reference     参考日期
 * @param {String} [format='all']  数据格式化类型，默认为 all [year,month,day,timestamp,date,morning,night,all]
 */
export function getNextDayDate(reference, format) {
    return getDatepicker(reference, 'nextDay', format)
}

/**
 * 获取近期的日期区间
 * @param {String} count 近期的数量
 * @param {String} [type='day']  近期的类型，默认为 day [year,month,day]
 */
export function getNearRange(count, type) {
    const result = {
        start: 0,
        end: Date.now()
    }

    switch (type) {
        case 'day':
            result.start = result.end - 86400000 * (count - 1)

            break
        case 'month':
            result.start = result.end - 86400000 * 30 * count + 86400000

            break
        case 'year':
            result.start = result.end - 86400000 * 365 * count + 86400000

            break
        default:
            break
    }

    return result
}

// utils/timer.js


export default formatDate
